#pragma once

#include <functional>
#include <map>
#include <string>
#include <vector>
#include "log/log_define.h"


namespace xlog {
    
struct log_msg;

/**
 * @brief 日志输出类
 */
class logger
{
public:
    logger() = default;
    logger(log_level log_level) {}
    logger(log_level log_level, const char* filename, uint32_t file_line, const char* func_name) {}
    ~logger();

public:
    using ptr = std::shared_ptr<logger>;

public:
    void set_level(const log_level level);

public:
    template<typename FormatString, typename... Args>
    void debug(const FormatString &fmt, Args&& ...args)
    {
        log(log_level::debug, fmt, std::forward<Args>(args)...);
    }

    template<typename FormatString, typename... Args>
    void info(const FormatString &fmt, Args&& ...args)
    {
        log(log_level::info, fmt, std::forward<Args>(args)...);
    }

    template<typename FormatString, typename... Args>
    void warn(const FormatString &fmt, Args&& ...args)
    {
        log(log_level::warn, fmt, std::forward<Args>(args)...);
    }

    template<typename FormatString, typename... Args>
    void error(const FormatString &fmt, Args&& ...args)
    {
        log(log_level::error, fmt, std::forward<Args>(args)...);
    }
public:

    template<typename FormatString, typename... Args>
    void log(log_level level, const FormatString &fmt, Args&&... args)
    {
        if (!m_log_enabled)
        {
            return;
        }
        log_memory_buf buf;
        fmt::format_to(buf, fmt, std::forward<Args>(args)...);
        std::string s(buf.data(), buf.size());
        printf("data: %s\n", s.c_str());
        log_msg msg(level, log_string_view(buf.data()));
        log_it(msg);
    }
protected:
    virtual void log_it(log_msg msg);
    
    virtual void flush();
private:
    /**
     * 日志具体实现
     */
    struct LogImpl
    {
        /// 日志流
        //LogStream m_stream;
    };

    /// 具体实现
    // LogImpl m_impl;

    // std::map<std::string, std::shared_ptr<LogChannel>> m_channels;
    // std::shared_ptr<LogWriter> m_writer;

    /// 日志开关
    bool m_log_enabled{ true };

    /// 日志等级
    log_level m_level{ log_level::debug };

    /// 日志接收器
    std::vector<log_sink_ptr> m_sinks;
};

}  // namespace xlog

#ifdef XLOG_HEADER_ONLY
#include "logger_inl.h"
#endif